package zzu.mxd.answer.serviceImpl;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import zzu.mxd.answer.vo.AnswerResult;
import zzu.mxd.answer.entity.Exercises;
import zzu.mxd.answer.entity.Recording;
import zzu.mxd.answer.mapper.ExercisesMapper;
import zzu.mxd.answer.service.IExercisesService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import zzu.mxd.answer.vo.ExercisesVO;
import zzu.mxd.common.R;
import zzu.mxd.utils.RedisUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * <p>
 * 题目表 服务实现类
 * </p>
 *
 * @author mxd
 * @since 2018-11-08
 */
@Service
@Slf4j
public class ExercisesServiceImpl extends ServiceImpl<ExercisesMapper, Exercises> implements IExercisesService {
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private ExercisesMapper exercisesMapper;
    @Value("${spring.redis.keyName.exercise}")
    private  String exercisesKey ;
    @Override
    public AnswerResult answerQuestion(List<ExercisesVO> exercisesVOList, String id) {
        AnswerResult answerResult = new AnswerResult();
        //计算答题率
        Integer correctNumber = 0;
        for (int i = 0; i < exercisesVOList.size(); i++) {
            if (exercisesVOList.get(i).judjeRight())
                correctNumber++;
        }
        answerResult.setCorrectNumber(correctNumber);
        answerResult.setIncorrectNumber(exercisesVOList.size() - correctNumber);
        answerResult.setRate(correctNumber / exercisesVOList.size());
        //批量插入答题记录
        List<Recording> recordings = new ArrayList<>();
        for (int i = 0; i < exercisesVOList.size(); i++) {
            Recording recording = new Recording();
            recording.setExercisesId(exercisesVOList.get(i).getExercises().getId());
            recording.setOption(exercisesVOList.get(i).getOption());
            recording.setStudentId(id);
            recording.setCreateTime(LocalDateTime.now());
            recording.setIsRight(exercisesVOList.get(i).judjeRight() ? 0 : 1);
            recording.setStatus(1);
            recordings.add(recording);
        }
        exercisesMapper.insertBatch(recordings);
        return answerResult;
    }

    @Override
    public List<Exercises> selectAll() {
        return exercisesMapper.selectList(null);
    }

    @Override
    public List<Exercises> getRandomExercises(int count, int subjectId) throws Exception {


        List<Exercises> exercises;
        //如果缓存存在
        if (redisUtils.exists(exercisesKey)) {
            Object object = redisUtils.get(exercisesKey);
            //Json转List
            exercises = JSON.parseArray(object.toString(), Exercises.class);
            //如果缓存不存在
        } else {
            log.error("exercises缓存不存在");
            throw new Exception("redis中exercise缓存不存在，获取失败");

        }
        //相应科目的List
        List<Exercises> subjectList = new ArrayList<>();
        for (Exercises exercise : exercises) {
            if (exercise.getSubjectId() == subjectId) {
                subjectList.add(exercise);
            }
        }
        return getRandomList(subjectList, count);
        //TODO 优化算法
    }

    /**
     * @param paramList:被抽取list
     * @param count:抽取元素的个数
     * @function:从list中随机抽取若干不重复元素
     * @return:由抽取元素组成的新list
     */
    private List getRandomList(List paramList, int count) {
        if (paramList.size() < count) {
            return paramList;
        }
        Random random = new Random();
        List<Integer> tempList = new ArrayList<>();
        List<Object> newList = new ArrayList();
        int temp;
        for (int i = 0; i < count; i++) {
            //将产生的随机数作为被抽list的索引
            temp = random.nextInt(paramList.size());
            if (!tempList.contains(temp)) {
                tempList.add(temp);
                newList.add(paramList.get(temp));
            } else {
                i--;
            }
        }
        return newList;
    }

}
